home *** CD-ROM | disk | FTP | other *** search
- /*
- Commodore 64 Emulator v0.4 Earle F. Philhower III
- Copyright (C) 1993-4 (st916w9r@dunx1.ocs.drexel.edu)
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include "Processor.h"
- #include "NewInstructions.h"
- #include "Stack.h"
- #include "Modes.h"
- #include "Error.h"
-
- extern byte bcd2dec[], dec2bcd[], cycletime[], scanCode[];
-
- /*
- This is my Instructions.c file condensed into one single routine.
- */
- void IntegratedProcessor(byte *Ga, byte *Gx, byte *Gy, byte *Gflags, byte *Gsp, word *Gpc,
- byte **Gmemory, byte *GRAM)
- {
- /*
- First we make local copies of the global variables. These *should* be stored
- within a register variable, but with TC, who knows!
- */
- register byte a, x, y, flags, sp;
- register word pc;
- register byte **memory, **memoryp1, *RAM;
-
- register byte tbyte;
- register word addr;
-
- int cycles, lines;
- byte oldMemoryMap;
-
- a=*Ga; x=*Gx; y=*Gy; flags=*Gflags; sp=*Gsp; pc=*Gpc;
- memory=Gmemory; memoryp1=memory+1; RAM=GRAM;
-
- oldMemoryMap=*RAMp1;
-
- lines=0;
- while (++lines<350)
- {
- cycles=0;
- while (cycles<35)
- {
- tbyte=ImmediateByte(); pc++;
- cycles+=cycletime[tbyte];
- switch (tbyte)
- {
- case 0x00:
- PushWord(pc);
- flags |= BKC;
- Push(flags|BKC);
- pc=WordAt(IrqTo);
- break;
- case 0x01:
- ORA(IndirectXAddr); pc++;
- break;
- case 0x02:
- CRS();
- break;
- case 0x03:
- LOR(IndirectXAddr); pc++;
- break;
- case 0x04:
- SKP(1);
- break;
- case 0x05:
- ORA(ZeroPageAddr); pc++;
- break;
- case 0x06:
- ASL(ZeroPageAddr); pc++;
- break;
- case 0x07:
- LOR(ZeroPageAddr); pc++;
- break;
- case 0x08:
- Push(flags);
- break;
- case 0x09:
- a |= ImmediateByte(); FlagsNZ(a); pc++;
- break;
- case 0x0a:
- if (a&128) flags |= CAR;
- else flags &= ~CAR;
- a=a<<1;
- FlagsNZ(a);
- break;
- case 0x0b:
- ANA(); pc++;
- break;
- case 0x0c:
- SKP(2);
- break;
- case 0x0d:
- ORA(AbsoluteAddr); pc+=2;
- break;
- case 0x0e:
- ASL(AbsoluteAddr); pc+=2;
- break;
- case 0x0f:
- LOR(AbsoluteAddr); pc+=2;
- break;
- case 0x10:
- BCL(NEG);
- break;
- case 0x11:
- ORA(IndirectYAddr); pc++;
- break;
- case 0x12:
- CRS();
- break;
- case 0x13:
- LOR(IndirectYAddr); pc++;
- break;
- case 0x14:
- SKP(1);
- break;
- case 0x15:
- ORA(ZeroPageXAddr); pc++;
- break;
- case 0x16:
- ASL(ZeroPageXAddr); pc++;
- break;
- case 0x17:
- LOR(ZeroPageXAddr); pc++;
- break;
- case 0x18:
- CLR(CAR);
- break;
- case 0x19:
- ORA(AbsoluteYAddr); pc+=2;
- break;
- case 0x1a:
- pc++;
- break;
- case 0x1b:
- LOR(AbsoluteYAddr); pc+=2;
- break;
- case 0x1c:
- SKP(2);
- break;
- case 0x1d:
- ORA(AbsoluteXAddr); pc+=2;
- break;
- case 0x1e:
- ASL(AbsoluteXAddr); pc+=2;
- break;
- case 0x1f:
- LOR(AbsoluteXAddr); pc+=2;
- break;
- case 0x20:
- PushWord(pc+1); pc=WordAt(pc);
- break;
- case 0x21:
- AND(IndirectXAddr); pc++;
- break;
- case 0x22:
- CRS();
- break;
- case 0x23:
- LAN(IndirectXAddr); pc+=2;
- break;
- case 0x24:
- BIT(ZeroPageAddr); pc++;
- break;
- case 0x25:
- AND(ZeroPageAddr); pc++;
- break;
- case 0x26:
- ROL(ZeroPageAddr); pc++;
- break;
- case 0x27:
- LAN(ZeroPageAddr); pc++;
- break;
- case 0x28:
- flags = Pop();
- break;
- case 0x29:
- a &= ImmediateByte(); FlagsNZ(a); pc++;
- break;
- case 0x2a:
- if (flags&CAR) {
- if ((a&128)==0) flags &=~CAR;
- a=(a<<1)|1; }
- else {
- if(a&128)flags|=CAR;
- a=a<<1; }
- FlagsNZ(a);
- break;
- case 0x2b:
- ANA(); pc++;
- break;
- case 0x2c:
- BIT(AbsoluteAddr); pc+=2;
- break;
- case 0x2d:
- AND(AbsoluteAddr); pc+=2;
- break;
- case 0x2e:
- ROL(AbsoluteAddr); pc+=2;
- break;
- case 0x2f:
- LAN(AbsoluteAddr); pc+=2;
- break;
- case 0x30:
- BST(NEG);
- break;
- case 0x31:
- AND(IndirectYAddr); pc++;
- break;
- case 0x32:
- CRS();
- break;
- case 0x33:
- LAN(IndirectYAddr); pc+=2;
- break;
- case 0x34:
- SKP(1);
- break;
- case 0x35:
- AND(ZeroPageXAddr); pc++;
- break;
- case 0x36:
- ROL(ZeroPageXAddr); pc++;
- break;
- case 0x37:
- LAN(ZeroPageXAddr); pc++;
- break;
- case 0x38:
- SET(CAR);
- break;
- case 0x39:
- AND(AbsoluteYAddr); pc+=2;
- break;
- case 0x3a:
- pc++;
- break;
- case 0x3b:
- LAN(AbsoluteYAddr); pc+=2;
- break;
- case 0x3c:
- SKP(2);
- break;
- case 0x3d:
- AND(AbsoluteXAddr); pc+=2;
- break;
- case 0x3e:
- ROL(AbsoluteXAddr); pc+=2;
- break;
- case 0x3f:
- LAN(AbsoluteXAddr); pc+=2;
- break;
- case 0x40:
- flags=Pop(); PopWord(pc);
- break;
- case 0x41:
- EOR(IndirectXAddr); pc++;
- break;
- case 0x42:
- CRS();
- break;
- case 0x43:
- REO(IndirectXAddr); pc+=2;
- break;
- case 0x44:
- SKP(1);
- break;
- case 0x45:
- EOR(ZeroPageAddr); pc++;
- break;
- case 0x46:
- LSR(ZeroPageAddr); pc++;
- break;
- case 0x47:
- REO(ZeroPageAddr); pc++;
- break;
- case 0x48:
- Push(a);
- break;
- case 0x49:
- a ^= ImmediateByte(); FlagsNZ(a); pc++;
- break;
- case 0x4a:
- flags &=~(CAR+NEG+ZER);
- if (a&1) flags |=CAR;
- if (a=a>>1); else flags |=ZER;
- break;
- case 0x4b:
- RBM(); pc++;
- break;
- case 0x4c:
- pc=WordAt(pc);
- break;
- case 0x4d:
- EOR(AbsoluteAddr); pc+=2;
- break;
- case 0x4e:
- LSR(AbsoluteAddr); pc+=2;
- break;
- case 0x4f:
- REO(AbsoluteAddr); pc+=2;
- break;
- case 0x50:
- BCL(OVF);
- break;
- case 0x51:
- EOR(IndirectYAddr); pc++;
- break;
- case 0x52:
- CRS();
- break;
- case 0x53:
- REO(IndirectYAddr); pc+=2;
- break;
- case 0x54:
- SKP(1);
- break;
- case 0x55:
- EOR(ZeroPageXAddr); pc++;
- break;
- case 0x56:
- LSR(ZeroPageXAddr); pc++;
- break;
- case 0x57:
- REO(ZeroPageXAddr); pc++;
- break;
- case 0x58:
- CLR(INT);
- break;
- case 0x59:
- EOR(AbsoluteYAddr); pc+=2;
- break;
- case 0x5a:
- pc++;
- break;
- case 0x5b:
- REO(AbsoluteYAddr); pc+=2;
- break;
- case 0x5c:
- SKP(2);
- break;
- case 0x5d:
- EOR(AbsoluteXAddr); pc+=2;
- break;
- case 0x5e:
- LSR(AbsoluteXAddr); pc+=2;
- break;
- case 0x5f:
- REO(AbsoluteXAddr); pc+=2;
- break;
- case 0x60:
- PopWord(pc); pc++;
- break;
- case 0x61:
- ADC(IndirectXAddr); pc++;
- break;
- case 0x62:
- CRS();
- break;
- case 0x63:
- RAD(IndirectXAddr); pc++;
- break;
- case 0x64:
- SKP(1);
- break;
- case 0x65:
- ADC(ZeroPageAddr); pc++;
- break;
- case 0x66:
- ROR(ZeroPageAddr); pc++;
- break;
- case 0x67:
- RAD(ZeroPageAddr); pc++;
- break;
- case 0x68:
- a=Pop(); FlagsNZ(a);
- break;
- case 0x69:
- addr=ImmediateByte();
- if (flags&DEC) {
- addr = bcd2dec[addr]+bcd2dec[a]+((flags&CAR)?1:0);
- flags &= ~(CAR+OVF+NEG+ZER);
- if (addr>99) {
- flags|=CAR+OVF;
- addr -=100; }
- if (addr==0) flags |= ZER;
- else flags |= addr&128;
- a=dec2bcd[addr];}
- else {
- addr += a+((flags&CAR)?1:0);
- flags &= ~(CAR+OVF+NEG+ZER);
- if (addr>255) {
- flags|=OVF+CAR;
- addr &=255; }
- if (addr==0) flags |= ZER;
- else flags |= addr&128;
- a=addr; }
- pc++;
- break;
- case 0x6a:
- if (flags&CAR) {
- if ((a&1)==0) flags &=~CAR;
- a=(a>>1)|128; }
- else {
- if(a&1) flags|=CAR;
- a=a>>1; }
- FlagsNZ(a);
- break;
- case 0x6b:
- RMAM(); pc++;
- break;
- case 0x6c:
- addr=WordAt(pc); pc=WordAt(addr);
- break;
- case 0x6d:
- ADC(AbsoluteAddr); pc+=2;
- break;
- case 0x6e:
- ROR(AbsoluteAddr); pc+=2;
- break;
- case 0x6f:
- RAD(AbsoluteAddr); pc+=2;
- break;
- case 0x70:
- BST(OVF);
- break;
- case 0x71:
- ADC(IndirectYAddr); pc++;
- break;
- case 0x72:
- CRS();
- break;
- case 0x73:
- RAD(IndirectYAddr); pc++;
- break;
- case 0x74:
- SKP(1);
- break;
- case 0x75:
- ADC(ZeroPageXAddr); pc++;
- break;
- case 0x76:
- ROR(ZeroPageXAddr); pc++;
- break;
- case 0x77:
- RAD(ZeroPageXAddr); pc++;
- break;
- case 0x78:
- SET(INT);
- break;
- case 0x79:
- ADC(AbsoluteYAddr); pc+=2;
- break;
- case 0x7a:
- pc++;
- break;
- case 0x7b:
- RAD(AbsoluteYAddr); pc+=2;
- break;
- case 0x7c:
- SKP(2);
- break;
- case 0x7d:
- ADC(AbsoluteXAddr); pc+=2;
- break;
- case 0x7e:
- ROR(AbsoluteXAddr); pc+=2;
- break;
- case 0x7f:
- RAD(AbsoluteXAddr); pc+=2;
- break;
- case 0x80:
- SKP(1);
- break;
- case 0x81:
- STA(IndirectXAddr); pc++;
- break;
- case 0x82:
- SKP(1);
- break;
- case 0x83:
- AAX(IndirectXAddr); pc++;
- break;
- case 0x84:
- STY(ZeroPageAddr); pc++;
- break;
- case 0x85:
- STA(ZeroPageAddr); pc++;
- break;
- case 0x86:
- STX(ZeroPageAddr); pc++;
- break;
- case 0x87:
- AAX(ZeroPageAddr); pc+=1;
- break;
- case 0x88:
- y--; FlagsNZ(y);
- break;
- case 0x89:
- SKP(1);
- break;
- case 0x8a:
- a=x; FlagsNZ(a);
- break;
- case 0x8b:
- XMA(); pc++;
- break;
- case 0x8c:
- STY(AbsoluteAddr); pc+=2;
- break;
- case 0x8d:
- STA(AbsoluteAddr); pc+=2;
- break;
- case 0x8e:
- STX(AbsoluteAddr); pc+=2;
- break;
- case 0x8f:
- AAX(AbsoluteAddr); pc+=2;
- break;
- case 0x90:
- BCL(CAR);
- break;
- case 0x91:
- STA(IndirectYAddr); pc++;
- break;
- case 0x92:
- CRS();
- break;
- case 0x93:
- AAX(IndirectYAddr); pc++;
- break;
- case 0x94:
- STY(ZeroPageXAddr); pc++;
- break;
- case 0x95:
- STA(ZeroPageXAddr); pc++;
- break;
- case 0x96:
- STX(ZeroPageYAddr); pc++;
- break;
- case 0x97:
- AAX(ZeroPageYAddr); pc++;
- break;
- case 0x98:
- a=y; FlagsNZ(a);
- break;
- case 0x99:
- STA(AbsoluteYAddr); pc+=2;
- break;
- case 0x9a:
- sp=x;
- break;
- case 0x9b:
- AXS(AbsoluteYAddr); pc+=2;
- break;
- case 0x9c:
- TEY(AbsoluteXAddr); pc+=2;
- break;
- case 0x9d:
- STA(AbsoluteXAddr); pc+=2;
- break;
- case 0x9e:
- TEX(AbsoluteYAddr); pc+=2;
- break;
- case 0x9f:
- TEA(AbsoluteYAddr); pc+=2;
- break;
- case 0xa0:
- y=ImmediateByte(); FlagsNZ(y); pc++;
- break;
- case 0xa1:
- LDA(IndirectXAddr); pc++;
- break;
- case 0xa2:
- x=ImmediateByte(); FlagsNZ(x); pc++;
- break;
- case 0xa3:
- LAX(IndirectXAddr); pc++;
- break;
- case 0xa4:
- LDY(ZeroPageAddr); pc++;
- break;
- case 0xa5:
- LDA(ZeroPageAddr); pc++;
- break;
- case 0xa6:
- LDX(ZeroPageAddr); pc++;
- break;
- case 0xa7:
- LAX(ZeroPageAddr); pc++;
- break;
- case 0xa8:
- y=a; FlagsNZ(y);
- break;
- case 0xa9:
- a=ImmediateByte(); FlagsNZ(a); pc++;
- break;
- case 0xaa:
- x=a; FlagsNZ(x);
- break;
- case 0xab:
- AMA(); pc++;
- break;
- case 0xac:
- LDY(AbsoluteAddr); pc+=2;
- break;
- case 0xad:
- LDA(AbsoluteAddr); pc+=2;
- break;
- case 0xae:
- LDX(AbsoluteAddr); pc+=2;
- break;
- case 0xaf:
- LAX(AbsoluteAddr); pc+=2;
- break;
- case 0xb0:
- BST(CAR);
- break;
- case 0xb1:
- LDA(IndirectYAddr); pc++;
- break;
- case 0xb2:
- CRS();
- break;
- case 0xb3:
- LAX(IndirectYAddr); pc++;
- break;
- case 0xb4:
- LDY(ZeroPageXAddr); pc++;
- break;
- case 0xb5:
- LDA(ZeroPageXAddr); pc++;
- break;
- case 0xb6:
- LDX(ZeroPageYAddr); pc++;
- break;
- case 0xb7:
- LAX(ZeroPageYAddr); pc++;
- break;
- case 0xb8:
- CLR(OVF);
- break;
- case 0xb9:
- LDA(AbsoluteYAddr); pc+=2;
- break;
- case 0xba:
- x=sp;
- break;
- case 0xbb:
- LAS(AbsoluteYAddr); pc+=2;
- break;
- case 0xbc:
- LDY(AbsoluteXAddr); pc+=2;
- break;
- case 0xbd:
- LDA(AbsoluteXAddr); pc+=2;
- break;
- case 0xbe:
- LDX(AbsoluteYAddr); pc+=2;
- break;
- case 0xbf:
- LAX(AbsoluteYAddr); pc+=2;
- break;
- case 0xc0:
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (y==tbyte) flags |=CAR+ZER;
- else if (y>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- break;
- case 0xc1:
- CMP(IndirectXAddr); pc++;
- break;
- case 0xc2:
- SKP(1);
- break;
- case 0xc3:
- DCP(IndirectXAddr); pc++;
- break;
- case 0xc4:
- CPY(ZeroPageAddr); pc++;
- break;
- case 0xc5:
- CMP(ZeroPageAddr); pc++;
- break;
- case 0xc6:
- DECR(ZeroPageAddr); pc++;
- break;
- case 0xc7:
- DCP(ZeroPageAddr); pc++;
- break;
- case 0xc8:
- y++; FlagsNZ(y);
- break;
- case 0xc9:
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (a==tbyte) flags |=CAR+ZER;
- else if (a>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- break;
- case 0xca:
- x--; FlagsNZ(x);
- break;
- case 0xcb:
- AXM(); pc++;
- break;
- case 0xcc:
- CPY(AbsoluteAddr); pc+=2;
- break;
- case 0xcd:
- CMP(AbsoluteAddr); pc+=2;
- break;
- case 0xce:
- DECR(AbsoluteAddr); pc+=2;
- break;
- case 0xcf:
- DCP(AbsoluteAddr); pc++;
- break;
- case 0xd0:
- BCL(ZER);
- break;
- case 0xd1:
- CMP(IndirectYAddr); pc++;
- break;
- case 0xd2:
- CRS();
- break;
- case 0xd3:
- DCP(IndirectYAddr); pc++;
- break;
- case 0xd4:
- SKP(1);
- break;
- case 0xd5:
- CMP(ZeroPageXAddr); pc++;
- break;
- case 0xd6:
- DECR(ZeroPageXAddr); pc++;
- break;
- case 0xd7:
- DCP(ZeroPageXAddr); pc++;
- break;
- case 0xd8:
- CLR(DEC);
- break;
- case 0xd9:
- CMP(AbsoluteYAddr); pc+=2;
- break;
- case 0xda:
- pc++;
- break;
- case 0xdb:
- DCP(AbsoluteYAddr); pc++;
- break;
- case 0xdc:
- SKP(2);
- break;
- case 0xdd:
- CMP(AbsoluteXAddr); pc+=2;
- break;
- case 0xde:
- DECR(AbsoluteXAddr); pc+=2;
- break;
- case 0xdf:
- DCP(AbsoluteXAddr); pc++;
- break;
- case 0xe0:
- tbyte=ImmediateByte();
- flags &=~(CAR+ZER+NEG);
- if (x==tbyte) flags |=CAR+ZER;
- else if (x>tbyte) flags |=CAR;
- else flags |=NEG;
- pc++;
- break;
- case 0xe1:
- SBC(IndirectXAddr); pc++;
- break;
- case 0xe2:
- SKP(1);
- break;
- case 0xe3:
- ISB(IndirectXAddr); pc++;
- break;
- case 0xe4:
- CPX(ZeroPageAddr); pc++;
- break;
- case 0xe5:
- SBC(ZeroPageAddr); pc++;
- break;
- case 0xe6:
- INCR(ZeroPageAddr); pc++;
- break;
- case 0xe7:
- ISB(ZeroPageAddr); pc++;
- break;
- case 0xe8:
- x++; FlagsNZ(x);
- break;
- case 0xe9:
- addr=ImmediateByte();
- if (flags&DEC) {
- addr = bcd2dec[a]-bcd2dec[addr]-((flags&CAR)?0:1);
- flags &= ~(CAR+ZER+NEG+OVF);
- if (addr==0) flags |=ZER+CAR;
- else if (((int)addr)>0) flags |=CAR;
- else {
- flags|=NEG;
- addr +=100; }
- a=dec2bcd[addr]; }
- else {
- addr = a-addr-((flags&CAR)?0:1);
- flags &=~(CAR+ZER+OVF+NEG);
- if (addr==0) flags |= ZER+CAR;
- else if (((int)addr)>0) flags |= CAR;
- else flags|=OVF;
- addr &= 255;
- flags |= addr&128;
- a=addr; }
- pc++;
- break;
- case 0xea:
- break;
- case 0xeb:
- addr=ImmediateByte();
- if (flags&DEC) {
- addr = bcd2dec[a]-bcd2dec[addr]-((flags&CAR)?0:1);
- flags &= ~(CAR+ZER+NEG+OVF);
- if (addr==0) flags |=ZER+CAR;
- else if (((int)addr)>0) flags |=CAR;
- else {
- flags|=NEG;
- addr +=100; }
- a=dec2bcd[addr]; }
- else {
- addr = a-addr-((flags&CAR)?0:1);
- flags &=~(CAR+ZER+OVF+NEG);
- if (addr==0) flags |= ZER+CAR;
- else if (((int)addr)>0) flags |= CAR;
- else flags|=OVF;
- addr &= 255;
- flags |= addr&128;
- a=addr; }
- pc++;
- break;
- case 0xec:
- CPX(AbsoluteAddr); pc+=2;
- break;
- case 0xed:
- SBC(AbsoluteAddr); pc+=2;
- break;
- case 0xee:
- INCR(AbsoluteAddr); pc+=2;
- break;
- case 0xef:
- ISB(AbsoluteAddr); pc+=2;
- break;
- case 0xf0:
- BST(ZER);
- break;
- case 0xf1:
- SBC(IndirectYAddr); pc++;
- break;
- case 0xf2:
- CRS();
- break;
- case 0xf3:
- ISB(IndirectYAddr); pc++;
- break;
- case 0xf4:
- SKP(1);
- break;
- case 0xf5:
- SBC(ZeroPageXAddr); pc++;
- break;
- case 0xf6:
- INCR(ZeroPageXAddr); pc++;
- break;
- case 0xf7:
- ISB(ZeroPageXAddr); pc++;
- break;
- case 0xf8:
- SET(DEC);
- break;
- case 0xf9:
- SBC(AbsoluteYAddr); pc+=2;
- break;
- case 0xfa:
- pc++;
- break;
- case 0xfb:
- ISB(AbsoluteYAddr); pc+=2;
- break;
- case 0xfc:
- SKP(2);
- break;
- case 0xfd:
- SBC(AbsoluteXAddr); pc+=2;
- break;
- case 0xfe:
- INCR(AbsoluteXAddr); pc+=2;
- break;
- case 0xff:
-
- /*
- This is out TRAP command for patching the ROMs. First make sure
- the global registers are set properly
- */
- *Ga=a; *Gx=x; *Gy=y; *Gflags=flags; *Gsp=sp; *Gpc=pc;
- TrapExecute();
- a=*Ga; x=*Gx; y=*Gy; flags=*Gflags; sp=*Gsp; pc=*Gpc;
- break;
- }
- /* Set up the keyboard register according to precomputed values */
- RAM[0xdc01]=scanCode[RAM[0xdc00]];
- }
- if (++RAM[0xd012]==0) RAM[0xd011] ^= 128;
- RAM[0xd018] |=1;
- }
- *Ga=a; *Gx=x; *Gy=y; *Gflags=flags; *Gsp=sp; *Gpc=pc;
- }
-
-